package lock

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/redis/go-redis/v9"
)

type ILocker interface {
	Lock(key string)
	UnLock(key string)
}

type RedisLock struct {
	client *redis.Client
	ctx    context.Context
	tll    time.Duration
	done   chan any
}

func NewRedisLock(client *redis.Client, ctx context.Context, ttl time.Duration) RedisLock {
	return RedisLock{
		client: client,
		ctx:    ctx,
		tll:    ttl,
		done:   nil,
	}
}
func (r *RedisLock) Lock(key string) {
	for {
		// 自旋上鎖
		result, err := r.client.SetNX(r.ctx, key, "value", r.tll).Result()
		if err != nil || !result {
			time.Sleep(100 * time.Millisecond)
			continue
		}

		break
	}

	r.done = make(chan any)
	select {
	case <-r.done:
		//解鎖成功
		return
	default:
		_, err := r.client.Expire(r.ctx, "key", r.tll).Result()
		if err != nil {
			log.Println(err)
		}

		fmt.Println("續期", key)
		<-time.After(r.tll / 2)
	}
}

func (r *RedisLock) UnLock(key string) {
	close(r.done)

	_, err := r.client.Del(r.ctx, key).Result()
	if err != nil {
		log.Println(err)
	}
}
